home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / os2 / octa209s.zip / octave-2.09 / src / error.cc < prev    next >
C/C++ Source or Header  |  1997-07-10  |  6KB  |  310 lines

  1. /*
  2.  
  3. Copyright (C) 1996 John W. Eaton
  4.  
  5. This file is part of Octave.
  6.  
  7. Octave is free software; you can redistribute it and/or modify it
  8. under the terms of the GNU General Public License as published by the
  9. Free Software Foundation; either version 2, or (at your option) any
  10. later version.
  11.  
  12. Octave is distributed in the hope that it will be useful, but WITHOUT
  13. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  14. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  15. for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Octave; see the file COPYING.  If not, write to the Free
  19. Software Foundation, 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  20.  
  21. */
  22.  
  23. #ifdef HAVE_CONFIG_H
  24. #include <config.h>
  25. #endif
  26.  
  27. #include <cstdarg>
  28. #include <cstring>
  29.  
  30. #include <string>
  31.  
  32. #include <strstream.h>
  33.  
  34. #include "defun.h"
  35. #include "error.h"
  36. #include "pager.h"
  37. #include "oct-obj.h"
  38. #include "utils.h"
  39. #include "ov.h"
  40. #include "variables.h"
  41.  
  42. // TRUE means that Octave will try to beep obnoxiously before printing
  43. // error messages.
  44. static bool Vbeep_on_error;
  45.  
  46. // Current error state.
  47. int error_state = 0;
  48.  
  49. // Tell the error handler whether to print messages, or just store
  50. // them for later.  Used for handling errors in eval() and
  51. // the `unwind_protect' statement.
  52. int buffer_error_messages;
  53.  
  54. // The message buffer
  55. ostrstream *error_message_buffer = 0;
  56.  
  57. static void
  58. verror (const char *name, const char *fmt, va_list args)
  59. {
  60.   flush_octave_stdout ();
  61.  
  62.   bool to_beep_or_not_to_beep_p = Vbeep_on_error && ! error_state;
  63.  
  64.   ostrstream output_buf;
  65.  
  66.   if (to_beep_or_not_to_beep_p)
  67.     output_buf << "\a";
  68.   if (name)
  69.     output_buf << name << ": ";
  70.   output_buf.vform (fmt, args);
  71.   output_buf << endl << ends;
  72.  
  73.   char *msg = output_buf.str ();
  74.  
  75.   if (buffer_error_messages)
  76.     {
  77.       char *ptr = msg;
  78.  
  79.       if (! error_message_buffer)
  80.     {
  81.       error_message_buffer = new ostrstream;
  82.  
  83.       // XXX FIXME XXX -- this is ugly, but it prevents
  84.       //
  85.       //   eval ("error (\"msg\")", "error (__error_text__)");
  86.       //
  87.       // from printing `error: ' twice.  Assumes that the NAME we
  88.       // have been given doesn't contain `:'.
  89.  
  90.       ptr = strchr (msg, ':') + 2;
  91.       ptr = ptr ? ptr : msg;      
  92.     }
  93.  
  94.       *error_message_buffer << ptr;
  95.     }
  96.   else
  97.     {
  98.       octave_diary << msg;
  99.       cerr << msg;
  100.     }
  101.  
  102.   delete [] msg;
  103. }
  104.  
  105. // Note that we don't actually print any message if the error string
  106. // is just "" or "\n".  This allows error ("") and error ("\n") to
  107. // just set the error state.
  108.  
  109. static void
  110. error_1 (const char *name, const char *fmt, va_list args)
  111. {
  112.   if (error_state != -2)
  113.     {
  114.       if (fmt)
  115.     {
  116.       if (*fmt)
  117.         {
  118.           int len = strlen (fmt);
  119.           if (fmt[len - 1] == '\n')
  120.         {
  121.           if (len > 1)
  122.             {
  123.               char *tmp_fmt = strsave (fmt);
  124.               tmp_fmt[len - 1] = '\0';
  125.               verror (name, tmp_fmt, args);
  126.               delete [] tmp_fmt;
  127.             }
  128.  
  129.           error_state = -2;
  130.         }
  131.           else
  132.         verror (name, fmt, args);
  133.         }
  134.     }
  135.       else
  136.     panic ("error_1: invalid format");
  137.  
  138.       if (! error_state)
  139.     error_state = 1;
  140.     }
  141. }
  142.  
  143. void
  144. message (const char *name, const char *fmt, ...)
  145. {
  146.   va_list args;
  147.   va_start (args, fmt);
  148.   verror (name, fmt, args);
  149.   va_end (args);
  150. }
  151.  
  152. void
  153. usage (const char *fmt, ...)
  154. {
  155.   va_list args;
  156.   va_start (args, fmt);
  157.   error_state = -1;
  158.   verror ("usage", fmt, args);
  159.   va_end (args);
  160. }
  161.  
  162. void
  163. warning (const char *fmt, ...)
  164. {
  165.   va_list args;
  166.   va_start (args, fmt);
  167.   verror ("warning", fmt, args);
  168.   va_end (args);
  169. }
  170.  
  171. void
  172. error (const char *fmt, ...)
  173. {
  174.   va_list args;
  175.   va_start (args, fmt);
  176.   error_1 ("error", fmt, args);
  177.   va_end (args);
  178. }
  179.  
  180. void
  181. parse_error (const char *fmt, ...)
  182. {
  183.   va_list args;
  184.   va_start (args, fmt);
  185.   error_1 (0, fmt, args);
  186.   va_end (args);
  187. }
  188.  
  189. void
  190. panic (const char *fmt, ...)
  191. {
  192.   flush_octave_stdout ();
  193.  
  194.   va_list args;
  195.   va_start (args, fmt);
  196.   verror ("panic", fmt, args);
  197.   va_end (args);
  198.   abort ();
  199. }
  200.  
  201. typedef void (*error_fun)(const char *, ...);
  202.  
  203. extern octave_value_list Fsprintf (const octave_value_list&, int);
  204.  
  205. static octave_value_list
  206. handle_message (error_fun f, const char *msg, const octave_value_list& args)
  207. {
  208.   octave_value_list retval;
  209.  
  210.   string tstr;
  211.  
  212.   int nargin = args.length ();
  213.  
  214.   if (nargin > 0)
  215.     {
  216.       octave_value arg;
  217.  
  218.       if (nargin > 1)
  219.     {
  220.       octave_value_list tmp = Fsprintf (args, 1);
  221.       arg = tmp(0);
  222.     }
  223.       else
  224.     arg = args(0);
  225.  
  226.       if (arg.is_defined ())
  227.     {
  228.       if (arg.is_string ())
  229.         {
  230.           tstr = arg.string_value ();
  231.           msg = tstr.c_str ();
  232.           
  233.           if (! msg)
  234.         return retval;
  235.         }
  236.       else if (arg.is_empty ())
  237.         return retval;
  238.     }
  239.     }
  240.  
  241. // Ugh.
  242.  
  243.   int len = strlen (msg);
  244.   if (msg[len - 1] == '\n')
  245.     {
  246.       if (len > 1)
  247.     {
  248.       char *tmp_msg = strsave (msg);
  249.       tmp_msg[len - 1] = '\0';
  250.       f ("%s\n", tmp_msg);
  251.       delete [] tmp_msg;
  252.     }
  253.     }
  254.   else
  255.     f ("%s", msg);
  256.  
  257.   return retval;
  258. }
  259.  
  260. DEFUN (error, args, ,
  261.   "error (FMT, ...): print message according to FMT and set error state.\n\
  262. \n\
  263. This should eventually take us up to the top level, possibly\n\
  264. printing traceback messages as we go.\n\
  265. \n\
  266. If the resulting error message ends in a newline character, traceback\n\
  267. messages are not printed.\n\
  268. \n\
  269. See also: printf") 
  270. {
  271.   return handle_message (error, "unspecified error", args);
  272. }
  273.  
  274. DEFUN (warning, args, ,
  275.   "warning (FMT, ...): print a warning message according to FMT.\n\
  276. \n\
  277. See also: error, printf")
  278. {
  279.   return handle_message (warning, "unspecified warning", args);
  280. }
  281.  
  282. DEFUN (usage, args, ,
  283.   "usage (FMT, ...): print a usage message according to FMT.\n\
  284. \n\
  285. See also: error, printf")
  286. {
  287.   return handle_message (usage, "unknown", args);
  288. }
  289.  
  290. static int
  291. beep_on_error (void)
  292. {
  293.   Vbeep_on_error = check_preference ("beep_on_error");
  294.  
  295.   return 0;
  296. }
  297.  
  298. void
  299. symbols_of_error (void)
  300. {
  301.   DEFVAR (beep_on_error, 0.0, 0, beep_on_error,
  302.     "if true, beep before printing error messages");
  303. }
  304.  
  305. /*
  306. ;;; Local Variables: ***
  307. ;;; mode: C++ ***
  308. ;;; End: ***
  309. */
  310.